﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.UI;

namespace HYView
{
	public class TileView
	{
		public ExternalCommandData Revit { get; set; }

		public string FirstViewTitle { get; set; }

		public string SecondViewTitle { get; set; }

		public Autodesk.Revit.DB.View FirstView { get; set; }

		public Autodesk.Revit.DB.View SecondView { get; set; }

		public List<string> UselessWindowName { get; set; }

		public List<IntPtr> LstSubWindow { get; set; }

		public List<IntPtr> LstUselessWindow { get; set; }

		public TileView(ExternalCommandData revit, string firstViewTitle, string secondViewTitle, List<string> uselessWindowName)
		{
			this.Revit = revit;
			this.FirstViewTitle = firstViewTitle;
			this.SecondViewTitle = secondViewTitle;
			this.UselessWindowName = uselessWindowName;
			this.LstUselessWindow = new List<IntPtr>();
			this.m_iUselessWindowCount = uselessWindowName.Count * 2;
			this.LstSubWindow = new List<IntPtr>();
		}

		public TileView(ExternalCommandData revit, Autodesk.Revit.DB.View firstView, Autodesk.Revit.DB.View secondView)
		{
			this.Revit = revit;
			this.FirstViewTitle = firstView.Title;
			this.SecondViewTitle = secondView.Title;
		}

		public void TileViewByViewName()
		{
			UIApplication application = this.Revit.Application;
			Document document = this.Revit.Application.ActiveUIDocument.Document;
			IntPtr intPtr = TileView.FindWindowEx(Process.GetCurrentProcess().MainWindowHandle, IntPtr.Zero, "MDIClient", "");
			TileView.RECT rect = default(TileView.RECT);
			TileView.GetWindowRect(intPtr, ref rect);
			int num = rect.Right - rect.Left;
			int height = rect.Bottom - rect.Top;
			foreach (string strTitle in this.UselessWindowName)
			{
				this.FindSubWindowSameViewTitle(intPtr, strTitle);
				foreach (IntPtr item in this.LstSubWindow)
				{
					this.LstUselessWindow.Add(item);
				}
			}
			foreach (IntPtr hwnd in this.LstUselessWindow)
			{
				TileView.ShowWindow(hwnd, 6);
			}
			if (this.FirstViewTitle.Contains(this.SecondViewTitle) || this.SecondViewTitle.Contains(this.FirstViewTitle))
			{
				this.FindSubWindowSameViewTitle(intPtr, this.FirstViewTitle);
				int count = this.LstSubWindow.Count;
				if (this.LstSubWindow.Count == 2)
				{
					TileView.ShowWindow(this.LstSubWindow[0], 1);
					TileView.MoveWindow(this.LstSubWindow[0], 0, 0, num / 2, height, true);
					TileView.SetWindowPos(this.LstSubWindow[0], -1, 0, 0, 0, 0, 3);
					TileView.SetForegroundWindow(this.LstSubWindow[0]);
					TileView.ShowWindow(this.LstSubWindow[1], 1);
					TileView.MoveWindow(this.LstSubWindow[1], num / 2, 0, num / 2, height, true);
					TileView.SetWindowPos(this.LstSubWindow[1], -1, 0, 0, 0, 0, 3);
					TileView.SetForegroundWindow(this.LstSubWindow[1]);
					return;
				}
			}
			else
			{
				this.FindSubWindowDiferViewTitle(intPtr, this.FirstViewTitle);
				this.FindSubWindowDiferViewTitle(intPtr, this.SecondViewTitle);
				if (this.m_FirstSubWindow == IntPtr.Zero || this.m_SecondSubWidnow == IntPtr.Zero)
				{
					return;
				}
				TileView.ShowWindow(this.m_FirstSubWindow, 1);
				TileView.MoveWindow(this.m_FirstSubWindow, 0, 0, num / 2, height, true);
				TileView.SetWindowPos(this.m_FirstSubWindow, -1, 0, 0, 0, 0, 3);
				TileView.SetForegroundWindow(this.m_FirstSubWindow);
				TileView.ShowWindow(this.m_SecondSubWidnow, 1);
				TileView.MoveWindow(this.m_SecondSubWidnow, num / 2, 0, num / 2, height, true);
				TileView.SetWindowPos(this.m_SecondSubWidnow, -1, 0, 0, 0, 0, 3);
				TileView.SetForegroundWindow(this.m_SecondSubWidnow);
			}
		}

		private void FindSubWindowSameViewTitle(IntPtr hwndParent, string strTitle)
		{
			this.LstSubWindow = new List<IntPtr>();
			TileView.EnumChildWindows(hwndParent, new TileView.EnumWindowsProc(this.EnumWindowsMethodSameViewTitle), strTitle);
		}

		private void FindSubWindowDiferViewTitle(IntPtr hwndParent, string strTitle)
		{
			this.LstSubWindow = new List<IntPtr>();
			TileView.EnumChildWindows(hwndParent, new TileView.EnumWindowsProc(this.EnumWindowsMethodDiferViewTitle), strTitle);
		}

		private bool EnumWindowsMethodSameViewTitle(IntPtr hWnd, string lParam)
		{
			TileView.RECT rect = default(TileView.RECT);
			IntPtr intPtr = Marshal.AllocHGlobal(200);
			TileView.GetWindowText(hWnd, intPtr, 200);
			string text = Marshal.PtrToStringAnsi(intPtr);
			if (text.IndexOf(lParam) != -1 && (text.IndexOf('{') == -1 || text.IndexOf('}') == -1))
			{
				TileView.GetWindowRect(hWnd, ref rect);
				if (!this.LstSubWindow.Contains(hWnd))
				{
					this.LstSubWindow.Add(hWnd);
				}
				if (this.LstSubWindow.Count == 2)
				{
					return false;
				}
			}
			return true;
		}

		private bool EnumWindowsMethodDiferViewTitle(IntPtr hWnd, string lParam)
		{
			this.LstSubWindow = new List<IntPtr>();
			IntPtr intPtr = Marshal.AllocHGlobal(200);
			TileView.GetWindowText(hWnd, intPtr, 200);
			string text = Marshal.PtrToStringAnsi(intPtr);
			if (this.m_FirstSubWindow == IntPtr.Zero)
			{
				if (text.IndexOf(lParam) != -1)
				{
					this.m_FirstSubWindow = hWnd;
					return false;
				}
			}
			else
			{
				if (!(this.m_FirstSubWindow != IntPtr.Zero) || !(this.m_SecondSubWidnow == IntPtr.Zero))
				{
					return false;
				}
				if (text.IndexOf(lParam) != -1)
				{
					this.m_SecondSubWidnow = hWnd;
					return false;
				}
			}
			return true;
		}

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

		[DllImport("user32.dll")]
		private static extern bool SetForegroundWindow(IntPtr hWnd);

		[DllImport("user32.dll", CharSet = CharSet.Auto)]
		private static extern int SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int Width, int Height, int flags);

		[DllImport("user32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool EnumChildWindows(IntPtr hwndParent, TileView.EnumWindowsProc lpEnumFunc, string lParam);

		[DllImport("user32.dll")]
		public static extern int GetWindowText(IntPtr hWnd, IntPtr lpString, int nMaxCount);

		[DllImport("User32.dll")]
		private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

		[DllImport("User32.dll")]
		private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);

		[DllImport("User32.dll", CharSet = CharSet.Auto)]
		public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint);

		[DllImport("user32.dll")]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool GetWindowRect(IntPtr hWnd, ref TileView.RECT lpRect);

		private void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
		{
			FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
			string transactionName = failuresAccessor.GetTransactionName();
			IList<FailureMessageAccessor> failureMessages = failuresAccessor.GetFailureMessages();
			if (failureMessages.Count == 0)
			{
				e.SetProcessingResult((FailureProcessingResult)0);
				return;
			}
			if (transactionName.Equals("create ramp"))
			{
				foreach (FailureMessageAccessor failureMessageAccessor in failureMessages)
				{
					failuresAccessor.DeleteWarning(failureMessageAccessor);
				}
				e.SetProcessingResult((FailureProcessingResult)1);
				return;
			}
			e.SetProcessingResult((FailureProcessingResult)0);
		}

		public IntPtr m_FirstSubWindow;

		public IntPtr m_SecondSubWidnow;

		private int m_iUselessWindowCount;

		public const int TOPMOST = -1;

		public const int BOTTOMMOST = 1;

		public enum ShowState
		{
			SW_HIDE,
			SW_SHOWNORMAL,
			SW_NORMAL = 1,
			SW_SHOWMINIMIZED,
			SW_SHOWMAXIMIZED,
			SW_MAXIMIZE = 3,
			SW_SHOWNOACTIVATE,
			SW_SHOW,
			SW_MINIMIZE,
			SW_SHOWMINNOACTIVE,
			SW_SHOWNA,
			SW_RESTORE,
			SW_SHOWDEFAULT,
			SW_FORCEMINIMIZE,
			SW_MAX = 11
		}

		public delegate bool EnumWindowsProc(IntPtr hWnd, string lParam);

		public struct RECT
		{
			public int Left;

			public int Top;

			public int Right;

			public int Bottom;
		}
	}
}
